package com.yyq.map;

import org.junit.Test;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *      /----Map:储存双列数据，储存key-value对的数据
 *              /----HashMap:作为Map的主要实现类，线程不安全，效率高；储存null的key和value
 *                      /----linkedHashMap:保证在遍历map元素时，可以按照添加的顺序实现遍历
 *                          原因:在原有的HashMap底层结构基础上，添加了一对双向指针
 *                          对于频繁的遍历操作，效率高
 *              /----TreeMap:保证按照添加的key-value对进行排序，实现排序遍历。此时考虑key的自然排序和定制排序
 *                          底层使用红黑树
 *              /----HashTable:作为古老的实现类，线程安全，效率低；不能储存null的key和value
 *                      /----Properties:常用来配置文件。key和value都是String类型。
 *      HashMap的底层:数组+链表（JDK7之前）
 *                   数组＋链表＋红黑树（JDK8）
*     二、Map结构的理解
 *      Map中的key无序的，不可重复的，使用Set存储所有的key  ---->key所在的类要重写equals()和hashcCode()方法
 *      Map中的value无序的，可重复的，使用Collection储存所有的value  ---->value所在的类重写equals()方法
 *      一个Key-value键值对构成了一个Entry对象。
 *      Map中的entry：无序的、不可重复的，使用Set存储所有的entry
 *
 *
 *     三、HashMap的底层实现原理
 *            Jdk7:
 *            HashMap map =new HashMap();
 *            在实例化之后，底层创建了长度是16的一维数组 Entry[] table
 *            ...可能执行很多put
 *            map.(key1,values1)
 *            首先，调用key1所在类的hashCode()方法计算key1的 哈希值，此哈希值经过某种算法计算之后，得到在Entry数组中的存放位置，
 *            如果此位置上数据为空，此时的key1-value1添加成功
 *            如果此位置上数据不为空，(意味着此位置存在一个或者多个数据(以链表的形式存在)),比较key1和已经存在的多个数据的hash值
 *                      如果key1的哈希值和已经存在的数据的哈希值都不同，此时key1-value1添加成功。
 *                      如果key1的哈希值和已经存在的数据(key2-value2)的哈希值相同，继续比较，调用key1所在类的equals(key2)
 *                              如果equals()返回false，则key1-value1添加成功
 *                              如果equals()返回为ture，则value1替换value2
 *
 *            在添加过程中，会涉及到扩容问题，默认的扩容是原来的二倍，并将原来的数据复制过来
 *
 *            Jdk8相较于jDk7的区别
 *
 *            1、new HashCode() ：底层没有创建一个长度为16的数组
 *            2、jdk8 底层数组为:Node[] 而非Entry[]
 *            3、首次调用put(key，value)方法时，底层创建长度为16的数组
 *            4、jdk7底层结构只有数组+链表
 *               jdk8底层结构 数组＋链表+红黑树
 *               当数组的某一个索引位置上的元素以链表形式存在的数据个数>8 且当前数组的长度＞64时，
 *               此时此索引位置上的所有数据改为红黑树储存
 *
 *
 * @author yyq
 * @create 2021-08-07 13:33
 */
public class MapStudy {
    @Test
    public void test1(){
        
    }
    @Test
    public void test(){
        Map map2=new HashMap();
        map2.put(21,"aa");
        map2.put(21122,"das");

        Map map=new HashMap();
        map.put(1,"aa");
        map.put(212,"das");
        map.put(21,"121");
        map.putAll(map2);
        //修改
        map.put(1,"修改后");
        System.out.println(map);
        //删除
        Object value = map.remove(1);
        System.out.println(value);
        System.out.println(map);
        //清空clear()
//        map.clear();
//        System.out.println(map);

        //11.6 Map接口：常用方法
        // 添加、删除、修改操作：
        // Object put(Object key,Object value)：将指定key-value添加到(或修改)当前map对象中
        // void putAll(Map m):将m中的所有key-value对存放到当前map中
        // Object remove(Object key)：移除指定key的key-value对，并返回value
        // void clear()：清空当前map中的所有数据
        // 元素查询的操作：
        // Object get(Object key)：获取指定key对应的value
        // boolean containsKey(Object key)：是否包含指定的key
        // boolean containsValue(Object value)：是否包含指定的value
        // int size()：返回map中key-value对的个数
        // boolean isEmpty()：判断当前map是否为空
        // boolean equals(Object obj)：判断当前map和参数对象obj是否相等
        Object o = map.get(21);
        System.out.println(o);
        boolean b = map.containsKey(21);


        // 元视图操作的方法：
        // Set keySet()：返回所有key构成的Set集合
        // Collection values()：返回所有value构成的Collection集合
        // Set entrySet()：返回所有key-value对构成的Set集合

    }
}
